/**
 * Definition of the @ref culstering_instance class and
 * signature of its methods.
 * A clustering_instance object describes de details
 * of a specific numeric clustering problem. It also
 * holds the data points.
 *
 * @author Carlos Colmentares (06-39380)
 * @author Kelwin Fernandez (07-40888)
 */

#ifndef __CLUSTROPHOBIA__CLUSTERING_INSTANCE_H_
#define __CLUSTROPHOBIA__CLUSTERING_INSTANCE_H_

#include <iostream>
#include <cstdlib>
#include <fstream>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <queue>
#include <cmath>

/**
 * Models a numeric clustering problem instance, with all
 * the details needed for it: the number of points, dimensions
 * of each observation, and other useful data.
 */
class clustering_instance{
    
    public:
        /**
         * The number of attributes that each observation in the
         * problem's instance data set has
         */
        int n_attributes;
        /**
         * The total number of observations in the data set
         */
        int n_data;
        /**
         * The observations in the data set
         */
        double** data;

        double* m;
        double* sd;

        /**
         * Constructs the class with the specified number
         * of attributes and initializes the structures for
         * reading the specified number of data points 
         * @param nattrib The number of attributes that each
         * observation in the data set will have
         * @param ndata The number of observations in the
         * data set
         */
        clustering_instance(int nattrib, int ndata);
        /**
         * Reads the indicated file and initializes the
         * instance with the read data
         * @param filename The path to the file to be
         * read
         */
        clustering_instance(int nattrib, int ndata, double** da);
        
        clustering_instance(std::string filename);
        /**
         * Returns the number of attributes that each
         * observation in the dataset has
         * @return The number of dimensions of each data point
         */
        int get_num_attributes();
        /**
         * Returns the total number of observations in the data set
         * @return The number of points in the data set
         */
        int get_num_data();
        /**
         * Returns a point which contains for each dimension
         * the mean of the data points
         * @return The mean of the data points
         */
        double* mean();
        /**
         * Returns a point which contains for each dimension
         * the standard deviation of the data points
         * @return The standard deviation of the data points
         */
        double* standard_deviation();
        /**
         * Normalizes the data set. This is made by dividing
         * each dimension of the points in the data by the
         * absolute value of the maximum value of that dimension
         * in the data set. Normalizing the data set will improve
         * the algorithms solutions for most of the cases
         */
        void normalize();
        /**
         * Undoes the action made by the normalize method. It
         * returns the data set to its original state
         */
        void un_normalize(double* v);
        void un_normalize();
};

#endif
